home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Power 1997 December
/
MACPOWER-1997-12.ISO.7z
/
MACPOWER-1997-12.ISO
/
AMUG
/
PROGRAMMING
/
Raven 1.2 Examples.sit
/
Raven 1.2 Examples
/
BoxPaint
/
Source
/
Pencil.cpp
< prev
next >
Wrap
Text File
|
1997-03-09
|
11KB
|
361 lines
/*
* File: Pencil.cpp
* Summary: A 3D mouse cursor in the shape of a pencil.
* Written by: Jesse Jones
*
* Copyright ゥ 1997 Jesse Jones.
* For conditions of distribution and use, see copyright notice in ZTypes.h
*
* Change History (most recent first):
*
* <-> 3/09/97 JDJ Created.
*/
#include "Pencil.h"
#include <Z3DCone.h>
#include <Z3DCylinder.h>
#include <Z3DIlluminationShaders.h>
#include <Z3DLine.h>
#include <Z3DRenderingLoops.h>
#include <Z3DTransforms.h>
#include <Z3DView.h>
// ===================================================================================
// class CPencil
// ===================================================================================
//---------------------------------------------------------------
//
// CPencil::~CPencil
//
//---------------------------------------------------------------
CPencil::~CPencil()
{
}
//---------------------------------------------------------------
//
// CPencil::CPencil
//
//---------------------------------------------------------------
CPencil::CPencil()
{
mShowOrientation = false; // don't show orientation
mCursorPlacement.location = kZero3DPt;
mCursorPlacement.toward = T3DVector(0.0, 0.0, 1.0);
mCursorPlacement.up = T3DVector(0.0, 1.0, 0.0);
mTransform = kIdentity3DMatrix; // no transform
mScale.x = 1.0; // no scale
mScale.y = 1.0;
mScale.z = 1.0;
// Create the pencil model.
this->CreatePencil();
// Don't want to be able to pick the cursor.
mPencilModel.RemoveState(kQ3DisplayGroupStateMaskIsPicked);
// Since the pencil doesn't have any attributes QD 3D doesn't
// need to push and pop the graphics state when rendering the
// pencil.
mPencilModel.AddState(kQ3DisplayGroupStateMaskIsInline);
// Create the orientation indicator.
this->CreateOrientationModel();
// Like the pencil model the orientation model shouldn't be
// picked and we can render it inline.
mOrientationModel.RemoveState(kQ3DisplayGroupStateMaskIsPicked);
mOrientationModel.AddState(kQ3DisplayGroupStateMaskIsInline);
// Make the pencil transparent
T3DColorRGB color(0.35, 0.35, 0.35);
mCursorAttributeSet.AddTransparencyColor(color);
// Finally, we don't want the cursor to be included in bounding operations
mPencilModel.AddState(kQ3DisplayGroupStateMaskUseBoundingBox | kQ3DisplayGroupStateMaskUseBoundingSphere);
mOrientationModel.AddState(kQ3DisplayGroupStateMaskUseBoundingBox | kQ3DisplayGroupStateMaskUseBoundingSphere);
this->Hide();
}
//---------------------------------------------------------------
//
// CPencil::Show
//
//---------------------------------------------------------------
void CPencil::Show()
{
mPencilModel.AddState(kQ3DisplayGroupStateMaskIsDrawn);
mOrientationModel.AddState(kQ3DisplayGroupStateMaskIsDrawn);
}
//---------------------------------------------------------------
//
// CPencil::Hide
//
//---------------------------------------------------------------
void CPencil::Hide()
{
mPencilModel.RemoveState(kQ3DisplayGroupStateMaskIsDrawn);
mOrientationModel.RemoveState(kQ3DisplayGroupStateMaskIsDrawn);
}
//---------------------------------------------------------------
//
// CPencil::MoveTo
//
//---------------------------------------------------------------
void CPencil::MoveTo(const S3DCursorLocation& loc)
{
T3DMatrix matrix = kIdentity3DMatrix;
// Get the last vector we need
T3DVector xAxis = CrossProduct(loc.up, loc.toward);
// This is a neat graphics trick stuff the normals into the
// matrix and it will automatically place your cursor with all
// the correct orientation.
matrix.value[0][0] = xAxis.x;
matrix.value[0][1] = xAxis.y;
matrix.value[0][2] = xAxis.z;
matrix.value[1][0] = loc.up.x;
matrix.value[1][1] = loc.up.y;
matrix.value[1][2] = loc.up.z;
matrix.value[2][0] = loc.toward.x;
matrix.value[2][1] = loc.toward.y;
matrix.value[2][2] = loc.toward.z;
// Stuff in the translation too
matrix.value[3][0] = loc.location.x;
matrix.value[3][1] = loc.location.y;
matrix.value[3][2] = loc.location.z;
mTransform = matrix;
}
//---------------------------------------------------------------
//
// CPencil::Submit
//
//---------------------------------------------------------------
void CPencil::Submit(const T3DView& view)
{
mCursorAttributeSet.Submit(view);
T3DMatrixTransform::Submit(mTransform, view);
T3DScaleTransform::Submit(mScale, view);
mOrientationModel.Submit(view);
mPencilModel.Submit(view);
}
//---------------------------------------------------------------
//
// CPencil::Scale
//
//---------------------------------------------------------------
void CPencil::Scale(const T3DDisplayGroup& model, const T3DView& view, float scale)
{
// For the purpose of this, we want to enable bounding
mPencilModel.AddState(kQ3DisplayGroupStateMaskUseBoundingBox);
mOrientationModel.AddState(kQ3DisplayGroupStateMaskUseBoundingBox);
// Get the two bounding boxes
T3DRect cursorBox;
T3DBoundingBoxLoop loop1(view, &cursorBox, kQ3ComputeBoundsExact);
do {
mPencilModel.Submit(view);
} while (loop1.Rendering());
T3DRect groupBox;
T3DBoundingBoxLoop loop2(view, &groupBox, kQ3ComputeBoundsExact);
do {
model.Submit(view);
} while (loop2.Rendering());
// Make sure there's stuff in it
if (!cursorBox.IsEmpty() && !groupBox.IsEmpty()) {
float theRatio = Distance(kZero3DPt, groupBox.size)/Distance(kZero3DPt, cursorBox.size);
// We scale it to match the model and then scale it based on the parameter
theRatio = fabs(theRatio)*scale;
mScale = T3DVector(theRatio, theRatio, theRatio);
}
// Don't forget to disable it when we are done
mPencilModel.RemoveState(kQ3DisplayGroupStateMaskUseBoundingBox);
mOrientationModel.RemoveState(kQ3DisplayGroupStateMaskUseBoundingBox);
}
#pragma mark ハ
//---------------------------------------------------------------
//
// CPencil::CreatePencil
//
//---------------------------------------------------------------
void CPencil::CreatePencil()
{
mPencilModel.AddObject(T3DLambertShader());
//
// HOW TO MAKE A PENCIL
//
mPencilModel.AddObject(T3DInterpolationStyle(kQ3InterpolationStyleVertex));
mPencilModel.AddObject(T3DSubdivisionStyle(kQ3SubdivisionMethodConstant, 6, 1));
// THE GRAPHITE
T3DAttributeSet graphiteAttributes;
T3DColorRGB color(0.25, 0.25, 0.25);
graphiteAttributes.AddDiffuseColor(color);
TQ3ConeData coneData;
coneData.origin = T3DPoint(0, 0, -1.0);
coneData.orientation = T3DVector(0, 0, 1.0);
coneData.majorRadius = T3DVector(0.26, 0.0, 0);
coneData.minorRadius = T3DVector(0.0, 0.26, 0);
coneData.uMin = 0.0;
coneData.uMax = 1.0;
coneData.vMin = 0.0;
coneData.vMax = 1.0;
coneData.caps = kQ3EndCapNone;
coneData.interiorAttributeSet = nil;
coneData.bottomAttributeSet = nil;
coneData.faceAttributeSet = nil;
coneData.coneAttributeSet = graphiteAttributes;
T3DCone graphite(coneData);
mPencilModel.AddObject(graphite);
// THE WOOD
T3DAttributeSet woodAttributes;
color = T3DColorRGB(0.75, 0.75, 0.25);
woodAttributes.AddDiffuseColor(color);
coneData.origin = T3DPoint(0, 0, -2.0);
coneData.orientation = T3DVector(0, 0, 2.0);
coneData.majorRadius = T3DVector(0.5, 0.0, 0);
coneData.minorRadius = T3DVector(0.0, 0.5, 0);
coneData.uMin = 0.0;
coneData.uMax = 1.0;
coneData.vMin = 0.0;
coneData.vMax = 1.0;
coneData.caps = kQ3EndCapNone;
coneData.interiorAttributeSet = nil;
coneData.bottomAttributeSet = nil;
coneData.faceAttributeSet = nil;
coneData.coneAttributeSet = woodAttributes;
T3DCone wood(coneData);
mPencilModel.AddObject(wood);
// THE ERASER
mPencilModel.AddObject(T3DSubdivisionStyle(kQ3SubdivisionMethodConstant, 12, 1));
T3DAttributeSet eraserAttributes;
color = T3DColorRGB(1.0, 0.5, 0.5);
eraserAttributes.AddDiffuseColor(color);
TQ3CylinderData cylinderData;
cylinderData.origin = T3DPoint(0, 0, -7.0);
cylinderData.orientation = T3DVector(0, 0, 1.0);
cylinderData.majorRadius = T3DVector(0.48, 0.0, 0);
cylinderData.minorRadius = T3DVector(0.0, 0.48, 0);
cylinderData.uMin = 0.0;
cylinderData.uMax = 1.0;
cylinderData.vMin = 0.0;
cylinderData.vMax = 1.0;
cylinderData.caps = kQ3EndCapMaskBottom;
cylinderData.interiorAttributeSet = nil;
cylinderData.topAttributeSet = nil;
cylinderData.bottomAttributeSet = nil;
cylinderData.faceAttributeSet = nil;
cylinderData.cylinderAttributeSet = eraserAttributes;
T3DCylinder eraser(cylinderData);
mPencilModel.AddObject(eraser);
// THE YELLOW PAINT
mPencilModel.AddObject(T3DSubdivisionStyle(kQ3SubdivisionMethodConstant, 6, 1));
mPencilModel.AddObject(T3DInterpolationStyle(kQ3InterpolationStyleNone));
T3DAttributeSet paintAttributes;
color = T3DColorRGB(1.0, 1.0, 0.0);
paintAttributes.AddDiffuseColor(color);
cylinderData.origin = T3DPoint(0, 0, -6.0);
cylinderData.orientation = T3DVector(0, 0, 4.0);
cylinderData.majorRadius = T3DVector(0.5, 0.0, 0);
cylinderData.minorRadius = T3DVector(0.0, 0.5, 0);
cylinderData.uMin = 0.0;
cylinderData.uMax = 1.0;
cylinderData.vMin = 0.0;
cylinderData.vMax = 1.0;
cylinderData.caps = kQ3EndCapNone;
cylinderData.interiorAttributeSet = nil;
cylinderData.topAttributeSet = nil;
cylinderData.bottomAttributeSet = nil;
cylinderData.faceAttributeSet = nil;
cylinderData.cylinderAttributeSet = paintAttributes;
T3DCylinder paint(cylinderData);
mPencilModel.AddObject(paint);
}
//---------------------------------------------------------------
//
// CPencil::CreateOrientationModel
//
//---------------------------------------------------------------
void CPencil::CreateOrientationModel()
{
mOrientationModel.AddObject(T3DLambertShader());
//
// HOW TO CREATE 3 SIMPLE LINES
//
// The x,y, and z axis are colored r,g and b, respectively
T3DAttributeSet attributes1;
T3DColorRGB color(1.0, 0.75, 0.75);
attributes1.AddDiffuseColor(color);
T3DLine line1(T3DPoint(0.0, 0.0, -0.01), T3DPoint(2.0, 0.0, -0.01), attributes1);
mOrientationModel.AddObject(line1);
T3DAttributeSet attributes2;
color = T3DColorRGB(0.75, 1.0, 0.75);
attributes2.AddDiffuseColor(color);
T3DLine line2(T3DPoint(0.0, 0.0, -0.01), T3DPoint(0.0, 2.0, -0.01), attributes2);
mOrientationModel.AddObject(line2);
T3DAttributeSet attributes3;
color = T3DColorRGB(0.75, 0.75, 1.0);
attributes3.AddDiffuseColor(color);
T3DLine line3(T3DPoint(0.0, 0.0, -0.01), T3DPoint(0.0, 0.0, 2.0), attributes3);
mOrientationModel.AddObject(line3);
}